~ function(){
	class Drag extends UserCustomEvent {
		constructor(el, params) {
			super()
			this.initParams(el, params)
			this.setElementHandle()
			this.bindEvent()
		}
		// 初始化参数
		initParams(el, params) {
			var options = {
				element: el, // 移动的元素
				handle: el, // 拖动的手柄
				axis: '', // 移动方向 x,y
				grid: null, // 网格 [20,20]
			}
			Object.assign(this, options, params)
			return this
		}
		// 设置拖动元素和拖动手柄
		setElementHandle(){
			var {element,handle} = this
			this._element = Drag.isDOM(element) ? element : document.querySelector(element);
			this._handle = Drag.isDOM(handle) ? handle : document.querySelector(handle);
		}
		// 绑定事件
		bindEvent(){
			this.handleDown = this.handleDown.bind(this)
			this.handleMove = this.handleMove.bind(this)
			this.handleUp = this.handleUp.bind(this)
			// _element的位置
			this.startPoint = {x:0,y:0}
			// 鼠标点击的位置
			this.mousePoint = {x:0,y:0}
			this._handle.addEventListener('mousedown',this.handleDown)
		}
		handleDown(ev){
			ev.preventDefault()
			this.startPoint.x = Drag.css(this._element,'left')
			this.startPoint.y = Drag.css(this._element,'top')
			this.mousePoint.x = ev.pageX
			this.mousePoint.y = ev.pageY
			// 点击鼠标，初始化_element偏移的位置
			this.offset = {x:0,y:0}
			document.addEventListener('mousemove',this.handleMove)
			document.addEventListener('mouseup',this.handleUp)
		}
		handleMove(ev){
			this.offset.x  = ev.pageX - this.mousePoint.x
			this.offset.y = ev.pageY - this.mousePoint.y
			
			// 设置网格
			this.setGrid()
			
			// 限制方向
			this.offset.y = this.axis==='x' ? 0:this.offset.y
			this.offset.x = this.axis==='y' ? 0:this.offset.x
			
			this.setValue(this.offset.x,this.offset.y)
		}
		handleUp(ev){
			this.transformElStyle()
			document.removeEventListener('mousemove',this.handleMove)
			document.removeEventListener('mouseup',this.handleUp)
		}
		// 拖动设置transform的偏移值
		setValue(x,y){
			this._element.style.transform = `translate(${x}px,${y}px)`
		}
		// 鼠标释放后，将transform偏移的值，增加到元素的left,top上，并清空transform
		transformElStyle(){
			Drag.css(this._element,{
				left:this.offset.x +this.startPoint.x+'px',
				top:this.offset.y +this.startPoint.y+'px',
				transform:''
			})
		}
		// 设置网格
		setGrid(){
			var grid = this.grid
			if(!grid) return false
			var gridArr = []
			if(typeof grid === 'number'){
				gridArr = [grid,grid]
			}else if(typeof grid === 'object' && 'length' in grid && grid.length){
				if(grid.length===1){
					gridArr = [grid[0],grid[0]]
				}else{
					gridArr = [grid[0],grid[1]]
				}
			}
			
			this.offset.x = this.setGridVal(gridArr[0],this.offset.x)
			this.offset.y = this.setGridVal(gridArr[1],this.offset.y)
		}
		/**
		 * 设置网格的位置
		 * @param {Object} grid 网格
		 * @param {Object} offset 偏移值
		 */
		setGridVal(grid,offset){
			return Math.floor(offset / grid) * grid
		}
		// 检测是否为dom元素
		static isDOM(obj) {
			return ((typeof HTMLElement === 'object') ?
				function() {
					return obj instanceof HTMLElement
				} :
				function() {
					return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'
				})()
		}
		static css(el,attr,value){
			if(typeof attr === 'string'){
				if(!value) return parseFloat(window.getComputedStyle(el)[attr])
				return el.style[attr] = value
			}
			if(typeof attr === 'object'){
				for(var key in attr){
					el.style[key] = attr[key]
				}
			}
		}
	}
	window.Drag = Drag
}()